package com.duobaoyu.dby.supply.biz.strategy.message.refund;

import com.duobaoyu.dby.channel.adapter.bean.message.refund.AfterSaleStatusMessage;
import com.duobaoyu.dby.channel.adapter.bean.refund.AfterSaleOrderInfo;
import com.duobaoyu.dby.channel.adapter.enums.ChannelCodeEnum;
import com.duobaoyu.dby.channel.boundary.bean.refund.result.AfterSaleParticularResult;
import com.duobaoyu.dby.supply.biz.constant.OperateSourceConstants;
import com.duobaoyu.dby.supply.common.biz.bo.refund.AfterSaleOutBO;
import com.duobaoyu.dby.supply.common.biz.bo.refund.AfterSaleStateContext;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author yw
 * @description
 * @date 2023/10/13 17:22
 */
@Slf4j
@Component
public class OriginalLifeAfterSaleStatusAsyncHandler extends AbstractChannelAfterSaleStateChangeHandler {
    @Override
    protected Set<String> channelCodes() {
        return Sets.newHashSet(ChannelCodeEnum.ORIGINAL_LIFE.getValue());
    }

    @Override
    protected Void handler(AfterSaleStateChangeMessageAsyncHandler.Context context,
                           Object beforeResult) {
        List<AfterSaleStatusMessage> channelAfterSaleMessages = context.getOriginMessages();
        List<AfterSaleOutBO> afterSaleItems = context.getAfterSales();

        Map<String, AfterSaleOutBO> afterSaleMap = afterSaleItems.stream()
                .collect(Collectors.toMap(AfterSaleOutBO::getChannelAfterSaleSn,
                        Function.identity(), (k1, k2) -> k1));

        List<AfterSaleStateContext> handleSuccessMessages = Lists.newArrayList();
        for (AfterSaleStatusMessage afterSaleMessage : channelAfterSaleMessages) {
            // 售后单号
            String channelAfterSaleNo = afterSaleMessage.getChannelAfterSaleSn();
            AfterSaleOutBO afterSale = afterSaleMap.get(channelAfterSaleNo);
            AfterSaleParticularResult result = afterSaleBoundaryClient.queryAfterSale(afterSale);

            AfterSaleOrderInfo afterSaleOrderInfo = result.getAfterSaleOrderInfo();
            List<AfterSaleStateContext.AfterSaleUpdateItemInfo> afterSaleUpdateItems = buildRefundInfo(afterSaleOrderInfo.getChannelRealRefundAmount(),
                    afterSaleOrderInfo.getChannelFreightRefundAmount(), afterSale);

            // 退款
            BigDecimal channelActualRefundAmount = null,
                    channelFreightActualRefundAmount = null;

            if (Objects.nonNull(afterSaleOrderInfo.getChannelRealRefundAmount())) {
                channelActualRefundAmount = afterSaleUpdateItems.stream().map(AfterSaleStateContext.AfterSaleUpdateItemInfo::getChannelActualRefundAmount)
                        .reduce(BigDecimal.ZERO, BigDecimal::add);
                channelFreightActualRefundAmount = afterSaleUpdateItems.stream().map(AfterSaleStateContext.AfterSaleUpdateItemInfo::getChannelFreightActualRefundAmount)
                        .reduce(BigDecimal.ZERO, BigDecimal::add);
            }
            AfterSaleStateContext afterSaleStateContext = new AfterSaleStateContext();
            afterSaleStateContext.setAfterSale(afterSale);
            afterSaleStateContext.setChangeContentOperate(AfterSaleStateContext.ChangeContentOperate.builder()
                    .afterSaleItemInfoList(afterSaleUpdateItems)
                    .channelActualRefundAmount(channelActualRefundAmount)
                    .channelFreightActualRefundAmount(channelFreightActualRefundAmount)
                    .build());
            afterSaleStateContext.setCurrentAfterSaleStatus(afterSaleOrderInfo.getAfterSaleStatus());
            afterSaleStateContext.setOperateSource(OperateSourceConstants.OPERATION_CHANNEL);
            handleSuccessMessages.add(afterSaleStateContext);
        }
        context.setHandleSuccessMessages(handleSuccessMessages);
        return null;
    }
}
